#! /bin/python3

import re
import os
import sys
import time
import argparse 
import textwrap
from concurrent.futures import ThreadPoolExecutor

default_ParallelNmu = 30

test_list = []
name_list = []
status_list = []

def test_check(name):
    log_name = "%s_sim_dir/sim_%s.log"%(name, name)
    file_exist = os.path.isfile(log_name)
    status = "finish"
    if file_exist :
        fd = open(log_name, "r")
        line = fd.readline()
        while line:
            ret = re.search("Passed", line)
            if ret:
                status = "passed"
                break
            else:
                status = "failed"
            line = fd.readline()
        fd.close()
    else :
        print(log_name + "is not exist")
        status = "failed"
    return status

def run_test(test, name, num):
    status_list[num] = "running"
    os.system("make sim REGRESS=1 %0s "%(test))
    status = test_check(name)
    status_list[num] = status
    return name

def test_done(response):
    dst_fd = open("result_regression.log", "w")
    dst_fd.write("No, %-50s,%s\n"%("testcase", "status"))
    num = 0
    for test_name, status in zip(name_list, status_list):
        num = num + 1
        # print("test_case:", test_name, "status:", status)
        dst_fd.write("%03d,%-50s,%s\n"%(num, test_name, status))
    dst_fd.close()
    os.system("cat result_regression.log")

def run_testsuite(list_file, comp_enable, immediately_start, ParallelNmu, regress_parm):
    if not "runlist" in list_file:
        print("Please select a file for runlist:")
        files = os.listdir(".")
        select_list = []
        index = 0
        for f in files:
            if "runlist" in f:
                print("[%0d]:%s"%(index, f))
                select_list.append(f)
                index = index + 1
        file_num = int(input("Select Num:"))
        list_file = select_list[file_num]
    #print("Open", list_file)
    src_fd = open(list_file, "r")
    line = src_fd.readline()
    while(line):
        ret1 = re.match("#?make.+", line)
        if(ret1):
            ret2 = re.search("TESTCASE.+", ret1.group())
            if(ret2):
                ret3 = re.match("TESTCASE=\S+", ret2.group())
                if(ret3):
                    test_list.append(ret2.group())
                    name_list.append(ret3.group()[9:])
                #print(ret2.group())
        line = src_fd.readline()
    print("collect test as this:")
    n = 0
    for name, test in zip(name_list, test_list):
        n = n + 1
        status_list.append("waiting")
        print("%03d, %09s, %-30s: make sim REGRESS=%0d %0s"%(n, status_list[n-1], name, regress_parm, test))
    if(immediately_start == 0):
        ret = input("Start running immediately? [y]")
        if(ret != "y"):
            ret = input("Do you want to Compile...? [y]")
            if(ret == "y"):
                comp_enable = 1
            else :
                comp_enable = 0
    if(comp_enable == 1):
        print("make comp REGRESS=%0d"%(regress_parm))
        if(os.system("make comp REGRESS=%0d"%(regress_parm))):
            print("exit...")
            return -1
    num = 0
    threadpool = ThreadPoolExecutor(ParallelNmu)
    for name, test in zip(name_list, test_list):
        futuer = threadpool.submit(run_test, test, name, num)
        futuer.add_done_callback(test_done)
        num = num + 1

def analyse_results(filedir):
    files = os.listdir(".")
    index = 0
    for f in files:
        ret = re.findall("(\S+)_sim_dir", f)
        if ret:
            name_list.append(ret[0])
            status = test_check(ret[0])
            status_list.append(status)
            print("[%0d] %s: %s"%(index, ret[0], status))
            index = index + 1
    test_done(0)

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Running regression or analyse results.', 
                                     epilog = 'Command example: "regress.py -r runlist" or "regress.py -a"')
    parser.add_argument('-a', '--analysis', dest='collect', action="store_true", help='analyse results after run finish')
    parser.add_argument('-r', '--run', dest='run', metavar='runlist', type=str, default="Null", help='specifies the testcase list file')
    parser.add_argument('-c', '--compile', dest='compile', action="store_true", help='need to recompile project')
    parser.add_argument('-i', '--immediately', dest='immediately', action="store_true", help='start running immediately')
    parser.add_argument('-p', '--parallel', dest='ParallelNmu', metavar=30, type=int, default=default_ParallelNmu, help='specifies the parallel nmuber')
    parser.add_argument('-g', '--regress', dest='regress_parm', action="store_true", help='set the argument for "REGRESS=1" otherwise "REGRESS=0"')
    args = parser.parse_args()
    if(args.collect == True):
        print("Collect results:")
        analyse_results('.')
    else:
        run_testsuite(args.run, args.compile, args.immediately, args.ParallelNmu, args.regress_parm)
    #print(args)


